package com.phonemap.service.server;

import java.util.Iterator;

import javax.xml.bind.JAXB;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SAAJResult;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.dom.DOMSource;

import com.phonemap.service.server.jaxws.CreateOrUpdatePosition;
import com.phonemap.service.server.jaxws.CreateOrUpdateUser;
import com.phonemap.service.server.jaxws.DeletePosition;
import com.phonemap.service.server.jaxws.DeleteUser;
import com.phonemap.service.server.jaxws.GetAllPositions;
import com.phonemap.service.server.jaxws.GetAllUsers;
import com.phonemap.service.server.jaxws.GetPosition;
import com.phonemap.service.server.jaxws.GetPositionsForUser;
import com.phonemap.service.server.jaxws.GetUser;

public class PhonemapSOAPHandler {

	private static final String NAMESPACE_URI = "http://server.service.phonemap.com/";

	private static final QName CREATE_OR_UPDATE_USER_QNAME = new QName(NAMESPACE_URI,"createOrUpdateUser");
	  private static final QName CREATE_OR_UPDATE_POSITION_QNAME = new QName(NAMESPACE_URI,"createOrUpdatePosition");
	  private static final QName DELETE_USER_QNAME = new QName(NAMESPACE_URI,"deleteUser");
	  private static final QName DELETE_POSITION_QNAME = new QName(NAMESPACE_URI,"deletePosition");
	  private static final QName GET_USER_QNAME = new QName(NAMESPACE_URI,"getUser");
	  private static final QName GET_ALL_USERS_QNAME = new QName(NAMESPACE_URI,"getAllUsers");
	  private static final QName GET_POSITION_QNAME = new QName(NAMESPACE_URI,"getPosition");
	  private static final QName GET_POSITIONS_FOR_USER_QNAME = new QName(NAMESPACE_URI,"getPositionsForUser");
	  private static final QName GET_ALL_POSITIONS_QNAME = new QName(NAMESPACE_URI,"getAllPositions");

	private MessageFactory messageFactory;
	private PhonemapAdapter greeterAdapter;

	public PhonemapSOAPHandler() throws SOAPException {
		messageFactory = MessageFactory.newInstance();
		greeterAdapter = new PhonemapAdapter();
	}

	@SuppressWarnings("rawtypes")
	  public SOAPMessage handleSOAPRequest(SOAPMessage request) throws SOAPException {
	    SOAPBody soapBody = request.getSOAPBody();
	    Iterator iterator = soapBody.getChildElements();
	    Object responsePojo = null;
	    QName qname = null;
	    while (iterator.hasNext()) {
	      Object next = iterator.next();
	      if (next instanceof SOAPElement) {
	        SOAPElement soapElement = (SOAPElement) next;
	        qname = soapElement.getElementQName();
	        
	          if(CREATE_OR_UPDATE_USER_QNAME.equals(qname)) {
	        	  responsePojo = handleCreateOrUpdateUserRequest(soapElement);
	        	  break;
	          } else if(CREATE_OR_UPDATE_POSITION_QNAME.equals(qname)) {
	        	  responsePojo = handleCreateOrUpdatePositionRequest(soapElement);
	        	  break;
	          } else if(DELETE_USER_QNAME.equals(qname)) {
	        	  responsePojo = handleDeleteUserRequest(soapElement);
	        	  break;
	          } else if(DELETE_POSITION_QNAME.equals(qname)) {
	        	  responsePojo = handleDeletePositionRequest(soapElement);
	        	  break;
	          } else if(GET_USER_QNAME.equals(qname)){
	        	  responsePojo = handleGetUserRequest(soapElement);
	        	  break;
	          } else if(GET_ALL_USERS_QNAME.equals(qname)){
	            responsePojo = handleGetAllUsersRequest(soapElement);
	            break;
	          } else if(GET_POSITION_QNAME.equals(qname)){
	            responsePojo = handleGetPositionRequest(soapElement);
	            break;
	          } else if(GET_POSITIONS_FOR_USER_QNAME.equals(qname)){
	            responsePojo = handleGetPositionsForUserRequest(soapElement);
	            break;
	          } else if(GET_ALL_POSITIONS_QNAME.equals(qname)){
	            responsePojo = handleGetAllPositionsRequest(soapElement);
	            break;
	          }
	      }
	    }
	    SOAPMessage soapResponse = messageFactory.createMessage();
	    soapBody = soapResponse.getSOAPBody();
	    if (responsePojo != null) {
	      JAXB.marshal(responsePojo, new SAAJResult(soapBody));
	    } else {
	      SOAPFault fault = soapBody.addFault();
	      fault.setFaultString("Unrecognized SOAP request." + qname.toString());
	    }
	    return soapResponse;
	  }
	  
	  private Object handleCreateOrUpdateUserRequest(SOAPElement soapElement){
		  CreateOrUpdateUser createUserRequest = JAXB.unmarshal(new DOMSource(soapElement), CreateOrUpdateUser.class);
		  return greeterAdapter.createOrUpdateUser(createUserRequest);
	  }
	  
	  private Object handleCreateOrUpdatePositionRequest(SOAPElement soapElement){
		  CreateOrUpdatePosition createOrUpdatePositionRequest = JAXB.unmarshal(new DOMSource(soapElement), CreateOrUpdatePosition.class);
		  return greeterAdapter.createOrUpdatePosition(createOrUpdatePositionRequest);
	  }
	  
	  private Object handleDeleteUserRequest(SOAPElement soapElement){
		  DeleteUser deleteUserRequest = JAXB.unmarshal(new DOMSource(soapElement), DeleteUser.class);
		  return greeterAdapter.deleteUser(deleteUserRequest);
	  }
	  
	  private Object handleDeletePositionRequest(SOAPElement soapElement){
		  DeletePosition deletePositionRequest = JAXB.unmarshal(new DOMSource(soapElement), DeletePosition.class);
		  return greeterAdapter.deletePosition(deletePositionRequest);
	  }
	  
	  private Object handleGetUserRequest(SOAPElement soapElement){
		  GetUser getUserRequest = JAXB.unmarshal(new DOMSource(soapElement), GetUser.class);
		  return greeterAdapter.getUser(getUserRequest);
	  }
	  
	  private Object handleGetAllUsersRequest(SOAPElement soapElement){
	    GetAllUsers getAllUsersRequest = JAXB.unmarshal(new DOMSource(soapElement), GetAllUsers.class);
	    return greeterAdapter.getAllUsers(getAllUsersRequest);
	  }
	  
	  private Object handleGetPositionRequest(SOAPElement soapElement){
	    GetPosition request = JAXB.unmarshal(new DOMSource(soapElement), GetPosition.class);
	    return greeterAdapter.getPosition(request);
	  }
	  
	  private Object handleGetPositionsForUserRequest(SOAPElement soapElement){
	    GetPositionsForUser request = JAXB.unmarshal(new DOMSource(soapElement), GetPositionsForUser.class);
	    return greeterAdapter.getPositionsForUser(request);
	  }
	  
	  private Object handleGetAllPositionsRequest(SOAPElement soapElement){
	    GetAllPositions request = JAXB.unmarshal(new DOMSource(soapElement), GetAllPositions.class);
	    return greeterAdapter.getAllPositions(request);
	  }
}
